#include "drv_serial.h"
#include "device.h"
#include "serial.h"


void stm32f4xx_uart_gpio_init(struct stm32f4xx_uart_data_s *port)
{
    LL_GPIO_InitTypeDef   GPIO_InitStruct  = {0};
    
	LL_AHB1_GRP1_EnableClock(port->txd->clock);
    LL_AHB1_GRP1_EnableClock(port->rxd->clock);
    
    GPIO_InitStruct.Pin        = port->txd->pin;
    GPIO_InitStruct.Mode       = LL_GPIO_MODE_ALTERNATE;
    GPIO_InitStruct.Speed      = LL_GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
    GPIO_InitStruct.Pull       = LL_GPIO_PULL_NO;
    GPIO_InitStruct.Alternate  = port->txd->alternate;
    LL_GPIO_Init(port->txd->port, &GPIO_InitStruct);
    
    GPIO_InitStruct.Pin        = port->rxd->pin;
    GPIO_InitStruct.Alternate  = port->rxd->alternate;
    LL_GPIO_Init(port->rxd->port, &GPIO_InitStruct);
}	

void stm32f4xx_uart_gpio_deinit(struct stm32f4xx_uart_data_s *port)
{
    LL_GPIO_InitTypeDef   GPIO_InitStruct  = {0};
    
    GPIO_InitStruct.Pin   = port->txd->pin;
    GPIO_InitStruct.Mode  = LL_GPIO_MODE_INPUT;
    GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW;
    GPIO_InitStruct.Pull  = LL_GPIO_PULL_NO;
    LL_GPIO_Init(port->txd->port, &GPIO_InitStruct);
    
    GPIO_InitStruct.Pin   = port->rxd->pin;
    GPIO_InitStruct.Alternate  = port->rxd->alternate;
    LL_GPIO_Init(port->rxd->port, &GPIO_InitStruct);
}	
	
int32_t stm32f4xx_uart_config(struct lt_serial_s *serial,struct lt_serial_cfg_s *cfg)
{
	struct stm32f4xx_uart_data_s *port = (struct stm32f4xx_uart_data_s *)serial->priv;
    LL_USART_InitTypeDef  USART_InitStruct = {0};
	
	if(port->enable_clock != NULL){
		port->enable_clock(port->clock);
	}else{
		return -1;
	}
    
    USART_InitStruct.BaudRate   = cfg->buad_rate;

    if (cfg->data_bits == DATA_BITS_8)
        USART_InitStruct.DataWidth  = LL_USART_DATAWIDTH_8B;

    if (cfg->stop_bits == STOP_BITS_1)
        USART_InitStruct.StopBits   = LL_USART_STOPBITS_1;
    else if (cfg->stop_bits == STOP_BITS_2)
        USART_InitStruct.StopBits   = LL_USART_STOPBITS_2;
    
    if(cfg->parity == PARITY_EVEN)
        USART_InitStruct.Parity     = LL_USART_PARITY_EVEN;
    else if(cfg->parity == PARITY_ODD)
        USART_InitStruct.Parity     = LL_USART_PARITY_ODD;
    else 
        USART_InitStruct.Parity     = LL_USART_PARITY_NONE;
    
    USART_InitStruct.TransferDirection   = LL_USART_DIRECTION_TX_RX;
    USART_InitStruct.HardwareFlowControl = LL_USART_HWCONTROL_NONE;
    USART_InitStruct.OverSampling        = LL_USART_OVERSAMPLING_16;
	
	LL_USART_Disable(port->USARTx);
    LL_USART_Init(port->USARTx, &USART_InitStruct);
    LL_USART_ConfigAsyncMode(port->USARTx);
	LL_USART_Enable(port->USARTx);
    
	return 0;
}
static void stm32f4xx_irq_config(struct lt_serial_s *serial)
{   
    struct stm32f4xx_uart_data_s *port = (struct stm32f4xx_uart_data_s *)serial->priv;

    NVIC_SetPriority(port->irq, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),port->irq_pre_pri, port->irq_sub_pri));
    NVIC_EnableIRQ(port->irq);
	
	LL_USART_DisableIT_TXE(port->USARTx);
    LL_USART_DisableIT_TC(port->USARTx);
    LL_USART_DisableIT_RXNE(port->USARTx);
	/* clear interrupt */
    LL_USART_ClearFlag_RXNE(port->USARTx);
	/* clear interrupt */
    LL_USART_ClearFlag_TC(port->USARTx);
}

void serial_dma_clear_flag_FE(DMA_TypeDef *DMAx,uint32_t Stream)
{
    uint32_t flag_pose[4] = {0x00000001,0x00000040,0x00010000,0x00400000};
    if(Stream >= LL_DMA_STREAM_4){
        DMAx->HIFCR |= flag_pose[Stream - LL_DMA_STREAM_4];
    }else{
        DMAx->LIFCR |= flag_pose[Stream];
    }
}

void serial_dma_clear_flag_DME(DMA_TypeDef *DMAx,uint32_t Stream)
{
    uint32_t flag_pose[4] = {0x00000004,0x00000100,0x00040000,0x01000000};
    if(Stream >= LL_DMA_STREAM_4){
        DMAx->HIFCR |= flag_pose[Stream - LL_DMA_STREAM_4];
    }else{
        DMAx->LIFCR |= flag_pose[Stream];
    }
}

void serial_dma_clear_flag_TE(DMA_TypeDef *DMAx,uint32_t Stream)
{
    uint32_t flag_pose[4] = {0x00000008,0x00000200,0x00080000,0x02000000};
    if(Stream >= LL_DMA_STREAM_4){
        DMAx->HIFCR |= flag_pose[Stream - LL_DMA_STREAM_4];
    }else{
        DMAx->LIFCR |= flag_pose[Stream];
    }
}

void serial_dma_clear_flag_HT(DMA_TypeDef *DMAx,uint32_t Stream)
{
    uint32_t flag_pose[4] = {0x00000010,0x00000400,0x00100000,0x04000000};
    if(Stream >= LL_DMA_STREAM_4){
        DMAx->HIFCR |= flag_pose[Stream - LL_DMA_STREAM_4];
    }else{
        DMAx->LIFCR |= flag_pose[Stream];
    }
}


void serial_dma_clear_flag_TC(DMA_TypeDef *DMAx,uint32_t Stream)
{
    uint32_t flag_pose[4] = {0x00000020,0x00000800,0x00200000,0x08000000};
    if(Stream >= LL_DMA_STREAM_4){
        DMAx->HIFCR |= flag_pose[Stream - LL_DMA_STREAM_4];
    }else{
        DMAx->LIFCR |= flag_pose[Stream];
    }
}


int32_t stm32f4_uart_init(struct lt_serial_s *serial)
{
	struct stm32f4xx_uart_data_s *port = (struct stm32f4xx_uart_data_s *)serial->priv;
	LL_USART_InitTypeDef  USART_InitStruct = {0};
	
	stm32f4xx_uart_gpio_init(port);
	stm32f4xx_uart_config(serial,&serial->cfg);
	
	if(port->enable_clock != NULL){
		port->enable_clock(port->clock);
	}else{
		return -1;
	}
    
    USART_InitStruct.BaudRate   = serial->cfg.buad_rate;
    if (serial->cfg.data_bits == DATA_BITS_8)
        USART_InitStruct.DataWidth  = LL_USART_DATAWIDTH_8B;
    if (serial->cfg.stop_bits == STOP_BITS_1)
        USART_InitStruct.StopBits   = LL_USART_STOPBITS_1;
    else if (serial->cfg.stop_bits == STOP_BITS_2)
        USART_InitStruct.StopBits   = LL_USART_STOPBITS_2;
    if(serial->cfg.parity == PARITY_EVEN)
        USART_InitStruct.Parity     = LL_USART_PARITY_EVEN;
    else if(serial->cfg.parity == PARITY_ODD)
        USART_InitStruct.Parity     = LL_USART_PARITY_ODD;
    else 
        USART_InitStruct.Parity     = LL_USART_PARITY_NONE;
    
    USART_InitStruct.TransferDirection   = LL_USART_DIRECTION_TX_RX;
    USART_InitStruct.HardwareFlowControl = LL_USART_HWCONTROL_NONE;
    USART_InitStruct.OverSampling        = LL_USART_OVERSAMPLING_16;
    LL_USART_Init(port->USARTx, &USART_InitStruct);
    LL_USART_ConfigAsyncMode(port->USARTx);
	stm32f4xx_irq_config(serial);
	
	LL_USART_Enable(port->USARTx);

	return 0;
}


int32_t stm32f4_uart_deinit(struct lt_serial_s *serial)
{
	struct stm32f4xx_uart_data_s *port = (struct stm32f4xx_uart_data_s *)serial->priv;
	
    NVIC_DisableIRQ(port->irq);
	stm32f4xx_uart_gpio_deinit(port);
    LL_USART_DeInit(port->USARTx);
	LL_USART_Disable(port->USARTx);

	return 0;
}

int32_t stm32f4_putc(struct lt_serial_s *serial,unsigned char ch)
{
    struct stm32f4xx_uart_data_s *port = (struct stm32f4xx_uart_data_s *)serial->priv;
	
	while(!LL_USART_IsActiveFlag_TXE(port->USARTx));
    LL_USART_TransmitData8(port->USARTx,ch);
	return 1;
}

int32_t stm32f4_getc(struct lt_serial_s *serial,unsigned char *ch)
{
    struct stm32f4xx_uart_data_s *port = (struct stm32f4xx_uart_data_s *)serial->priv;
	
    if(LL_USART_IsActiveFlag_RXNE(port->USARTx) != RESET)
    {
        *ch = LL_USART_ReceiveData8(port->USARTx);
        port->new_data_from_int = 0;
		return 1;
    }
    
	if(port->new_data_from_int & 0x10000000){
		*ch = port->new_data_from_int & 0x00000ff;
		port->new_data_from_int = 0;
		return 1;
	}
	return 0;
}

void stm32f4_enable_irq(struct lt_serial_s *serial,int32_t irq)
{
	struct stm32f4xx_uart_data_s *port = (struct stm32f4xx_uart_data_s *)serial->priv;
	if(irq == SERIAL_INT_TXDONE){
        LL_USART_EnableIT_TC(port->USARTx);
	}else if(irq == SERIAL_INT_RXDONE){
		LL_USART_EnableIT_RXNE(port->USARTx);
	}else if(irq == SERIAL_INT_DMATXDONE){
        if(port->dma_tx != NULL){
            LL_DMA_EnableIT_TC(port->dma_tx->dma,port->dma_tx->stream);
        }
	}else if(irq == SERIAL_INT_DMARXDONE){
		if(port->dma_rx != NULL){
            LL_DMA_EnableIT_TC(port->dma_rx->dma,port->dma_rx->stream);
        }
	}else if(irq == SERIAL_INT_IDLE){
        LL_USART_EnableIT_IDLE(port->USARTx);
	}
}

void stm32f4_disable_irq(struct lt_serial_s *serial,int32_t irq)
{
	struct stm32f4xx_uart_data_s *port = (struct stm32f4xx_uart_data_s *)serial->priv;
	if(irq == SERIAL_INT_TXDONE){
		LL_USART_DisableIT_TC(port->USARTx);
	}else if(irq == SERIAL_INT_RXDONE){
		LL_USART_DisableIT_RXNE(port->USARTx);
	}else if(irq == SERIAL_INT_DMATXDONE){
        if(port->dma_tx != NULL){
            LL_DMA_DisableIT_TC(port->dma_tx->dma,port->dma_tx->stream);
        }
	}else if(irq == SERIAL_INT_DMARXDONE){
		if(port->dma_rx != NULL){
            LL_DMA_DisableIT_TC(port->dma_rx->dma,port->dma_rx->stream);
        }
	}else if(irq == SERIAL_INT_IDLE){
        LL_USART_DisableIT_IDLE(port->USARTx);
	}
}

int32_t stm32f4_dma_send_start(struct lt_serial_s *serial,int32_t size)
{
    struct stm32f4xx_uart_data_s *port = (struct stm32f4xx_uart_data_s *)serial->priv;
    
    serial_dma_clear_flag_TC(port->dma_tx->dma, port->dma_tx->stream);
    serial_dma_clear_flag_HT(port->dma_tx->dma, port->dma_tx->stream);
    
    LL_DMA_DisableStream(port->dma_tx->dma, port->dma_tx->stream);
    LL_DMA_SetDataLength(port->dma_tx->dma, port->dma_tx->stream, size);
    LL_DMA_EnableStream(port->dma_tx->dma, port->dma_tx->stream);
    
    return size;
}


void stm32f4_dma_send_enable(struct lt_serial_s *serial)
{
    struct stm32f4xx_uart_data_s *port = (struct stm32f4xx_uart_data_s *)serial->priv;
    
    if(port->dma_tx == NULL){
        return;
    }
    
    if(port->dma_tx->dma != NULL){
        if(port->dma_tx->dma == DMA1){
            LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_DMA1);
        }else if(port->dma_tx->dma == DMA2){
            LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_DMA2);
        }
    
        LL_DMA_SetChannelSelection(port->dma_tx->dma, port->dma_tx->stream, port->dma_tx->channel);
        LL_DMA_SetDataTransferDirection(port->dma_tx->dma, port->dma_tx->stream, LL_DMA_DIRECTION_MEMORY_TO_PERIPH);
        LL_DMA_SetStreamPriorityLevel(port->dma_tx->dma, port->dma_tx->stream, LL_DMA_PRIORITY_LOW);
        LL_DMA_SetMode(port->dma_tx->dma, port->dma_tx->stream, LL_DMA_MODE_NORMAL);
        LL_DMA_SetPeriphIncMode(port->dma_tx->dma, port->dma_tx->stream, LL_DMA_PERIPH_NOINCREMENT);
        LL_DMA_SetMemoryIncMode(port->dma_tx->dma, port->dma_tx->stream, LL_DMA_MEMORY_INCREMENT);
        LL_DMA_SetPeriphSize(port->dma_tx->dma, port->dma_tx->stream, LL_DMA_PDATAALIGN_BYTE);
        LL_DMA_SetMemorySize(port->dma_tx->dma, port->dma_tx->stream, LL_DMA_MDATAALIGN_BYTE);
        LL_DMA_DisableFifoMode(port->dma_tx->dma, port->dma_tx->stream);
        
        LL_DMA_SetMemoryAddress(port->dma_tx->dma, port->dma_tx->stream, (uint32_t)serial->dma_tx_buffer);
        LL_DMA_SetPeriphAddress(port->dma_tx->dma, port->dma_tx->stream, (uint32_t)&(port->USARTx->DR));
        LL_DMA_SetDataLength(port->dma_tx->dma, port->dma_tx->stream, 0);
        
        NVIC_SetPriority(port->dma_tx->irq, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),port->dma_tx->irq_pre_pri, port->dma_tx->irq_sub_pri));
        NVIC_EnableIRQ(port->dma_tx->irq);
        
        LL_USART_EnableDMAReq_TX(port->USARTx);
    }
    
}

void stm32f4_dma_send_disable(struct lt_serial_s *serial)
{
    struct stm32f4xx_uart_data_s *port = (struct stm32f4xx_uart_data_s *)serial->priv;
    
    LL_USART_DisableDMAReq_TX(port->USARTx);
    
    if(port->dma_tx == NULL){
        return;
    }
    
    LL_DMA_DisableStream(port->dma_tx->dma, port->dma_tx->stream);
}

void stm32f4_dma_rx_init(struct lt_serial_s *serial)
{
    struct stm32f4xx_uart_data_s *port = (struct stm32f4xx_uart_data_s *)serial->priv;
    
    if(port->dma_rx == NULL){
        return;
    }
    
    if(port->dma_rx->dma != NULL){
        if(port->dma_rx->dma == DMA1){
            LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_DMA1);
        }else if(port->dma_rx->dma == DMA2){
            LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_DMA2);
        }
    
        LL_DMA_SetChannelSelection(port->dma_rx->dma, port->dma_rx->stream, port->dma_rx->channel);
        LL_DMA_SetDataTransferDirection(port->dma_rx->dma, port->dma_rx->stream, LL_DMA_DIRECTION_PERIPH_TO_MEMORY);
        LL_DMA_SetStreamPriorityLevel(port->dma_rx->dma, port->dma_rx->stream, LL_DMA_PRIORITY_LOW);
        LL_DMA_SetMode(port->dma_rx->dma, port->dma_rx->stream, LL_DMA_MODE_CIRCULAR);
        LL_DMA_SetPeriphIncMode(port->dma_rx->dma, port->dma_rx->stream, LL_DMA_PERIPH_NOINCREMENT);
        LL_DMA_SetMemoryIncMode(port->dma_rx->dma, port->dma_rx->stream, LL_DMA_MEMORY_INCREMENT);
        LL_DMA_SetPeriphSize(port->dma_rx->dma, port->dma_rx->stream, LL_DMA_PDATAALIGN_BYTE);
        LL_DMA_SetMemorySize(port->dma_rx->dma, port->dma_rx->stream, LL_DMA_MDATAALIGN_BYTE);
        LL_DMA_DisableFifoMode(port->dma_rx->dma, port->dma_rx->stream);
        
        LL_DMA_SetMemoryAddress(port->dma_rx->dma, port->dma_rx->stream, (uint32_t)serial->dma_rx_buffer);
        LL_DMA_SetPeriphAddress(port->dma_rx->dma, port->dma_rx->stream, (uint32_t)&(port->USARTx->DR));
        LL_DMA_SetDataLength(port->dma_rx->dma, port->dma_rx->stream, SERIAL_DMA_RX_BUFFER_LENGTH);

        NVIC_SetPriority(port->dma_rx->irq, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),port->dma_tx->irq_pre_pri, port->dma_tx->irq_sub_pri));
        NVIC_EnableIRQ(port->dma_rx->irq);
    
        LL_DMA_EnableStream(port->dma_rx->dma, port->dma_rx->stream);
        LL_DMA_ClearFlag_TC2(port->dma_rx->dma);
        LL_USART_EnableDMAReq_RX(port->USARTx);
    }
}


int32_t stm32f4_dma_rx_get_data_length(struct lt_serial_s *serial)
{
    struct stm32f4xx_uart_data_s *port = (struct stm32f4xx_uart_data_s *)serial->priv;
    
    if(port == NULL){
        return 0;
    }
    
    return SERIAL_DMA_RX_BUFFER_LENGTH - LL_DMA_GetDataLength(port->dma_rx->dma, port->dma_rx->stream);
}

struct lt_serial_s           *stm32_serial[8];

void stm32f4_serial_register(char *name,struct lt_serial_s *serial,struct stm32f4xx_uart_data_s *uart,uint16_t flag)
{	
	serial->putc         = stm32f4_putc;
	serial->getc         = stm32f4_getc;
	serial->enable_irq   = stm32f4_enable_irq;
	serial->disable_irq  = stm32f4_disable_irq; 
	serial->init         = stm32f4_uart_init;
    serial->deinit       = stm32f4_uart_deinit;
	serial->configure    = stm32f4xx_uart_config;
	serial->cfg          = serial_default_cfg;
	serial->priv         = uart;
    
    // serial->dma_tx_init    = stm32f4_dma_send_enable;
    // serial->dma_tx_disable = stm32f4_dma_send_disable;
    // serial->dma_tx_start   = stm32f4_dma_send_start;
    
    // serial->dma_rx_init    = stm32f4_dma_rx_init;
    // serial->dma_rx_get_data_length = stm32f4_dma_rx_get_data_length;
	
	if(uart->USARTx == USART1){
		stm32_serial[0] = serial;
	}
	
	if(uart->USARTx == USART2){
		stm32_serial[1] = serial;
	}
	
	if(uart->USARTx == USART3){
		stm32_serial[2] = serial;
	}
	
	if(uart->USARTx == UART4){
		stm32_serial[3] = serial;
	}
	
	if(uart->USARTx == UART5){
		stm32_serial[4] = serial;
	}
	
	if(uart->USARTx == USART6){
		stm32_serial[5] = serial;
	}

#if defined (STM32F423xx) || defined (STM32F427xx) || defined (STM32F429xx) || \
    defined (STM32F437xx) || defined (STM32F439xx) || defined (STM32F469xx) || \
	defined (STM32F479xx)                                                                                                                                                                          
    
    if(uart->USARTx == UART7){
		stm32_serial[6] = serial;
	}
    
    if(uart->USARTx == UART8){
		stm32_serial[7] = serial;
	}

#endif
	
	serial_device_register(serial,name,flag);
}

void uart_irq_handler(struct lt_serial_s *serial)
{
    struct stm32f4xx_uart_data_s *port = (struct stm32f4xx_uart_data_s *)serial->priv;
    
    if(LL_USART_IsActiveFlag_RXNE(port->USARTx) != RESET){
        port->new_data_from_int  = 0x10000000;
		port->new_data_from_int |= (LL_USART_ReceiveData8(port->USARTx) & 0x0000ffff);
        serial_isr(serial, SERIAL_INT_RXDONE);
        LL_USART_ClearFlag_RXNE(port->USARTx);
    }
    
    if(LL_USART_IsActiveFlag_TC(port->USARTx) != RESET){
        serial_isr(serial, SERIAL_INT_TXDONE);
        LL_USART_ClearFlag_TC(port->USARTx);
    }

    if(LL_USART_IsEnabledIT_IDLE(port->USARTx) == SET){
        if(LL_USART_IsActiveFlag_IDLE(port->USARTx) != RESET){

            if((port->dma_rx != NULL) && (serial->dev.open_flag & LT_DEVICE_FLAG_DMA_RX)){
                LL_DMA_DisableStream(port->dma_rx->dma,port->dma_rx->stream);
            }

            serial_isr(serial, SERIAL_INT_IDLE);

            if((port->dma_rx != NULL) && (serial->dev.open_flag & LT_DEVICE_FLAG_DMA_RX)){
                LL_DMA_SetDataLength(port->dma_rx->dma, port->dma_rx->stream, SERIAL_DMA_RX_BUFFER_LENGTH);
                LL_DMA_EnableStream(port->dma_rx->dma, port->dma_rx->stream);
                serial_dma_clear_flag_TC(port->dma_rx->dma, port->dma_rx->stream);
            }

            LL_USART_ClearFlag_IDLE(port->USARTx);
        }
    }

}


void USART1_IRQHandler(void)
{
	/* enter interrupt */
    
    uart_irq_handler(stm32_serial[0]);
    /* exit interrupt */
    
}


void USART2_IRQHandler(void)
{
	/* enter interrupt */
    
    uart_irq_handler(stm32_serial[1]);
    /* exit interrupt */
    
}


void USART3_IRQHandler(void)
{
	/* enter interrupt */
    
    uart_irq_handler(stm32_serial[2]);
    /* exit interrupt */
    
}

void UART4_IRQHandler(void)
{
	/* enter interrupt */
    
    uart_irq_handler(stm32_serial[3]);
    /* exit interrupt */
    
}

void UART5_IRQHandler(void)
{

	/* enter interrupt */
            
    uart_irq_handler(stm32_serial[4]);
    /* exit interrupt */
    
}

void USART6_IRQHandler(void)
{   
	/* enter interrupt */
    
    uart_irq_handler(stm32_serial[5]);
    /* exit interrupt */
    
}

void UART7_IRQHandler(void)
{
    /* enter interrupt */
     
    uart_irq_handler(stm32_serial[7]);
    /* exit interrupt */
    
}

void UART8_IRQHandler(void)
{  
	/* enter interrupt */
    
    uart_irq_handler(stm32_serial[7]);
    /* exit interrupt */
    
}


// DMA handler for uart5 rx
void DMA1_Stream0_IRQHandler(void)
{
    /* enter interrupt */
    

    if(LL_DMA_IsActiveFlag_TC0(DMA1) != RESET){
        LL_DMA_DisableStream(DMA1, LL_DMA_STREAM_0);
        serial_isr(stm32_serial[4],SERIAL_INT_DMARXDONE);
        LL_DMA_SetDataLength(DMA1, LL_DMA_STREAM_0, SERIAL_DMA_RX_BUFFER_LENGTH);
        LL_DMA_EnableStream(DMA1, LL_DMA_STREAM_0);
        LL_DMA_ClearFlag_TC0(DMA1);
    }
    
    if(LL_DMA_IsActiveFlag_HT0(DMA1) != RESET){
        LL_DMA_ClearFlag_HT0(DMA1);
    }
    
    if(LL_DMA_IsActiveFlag_TE0(DMA1) != RESET){
        LL_DMA_ClearFlag_TE0(DMA1);
    }
    
    if(LL_DMA_IsActiveFlag_DME0(DMA1) != RESET){
        LL_DMA_ClearFlag_DME0(DMA1);
    }
    /* exit interrupt */
    
}

//void DMA1_Stream1_IRQHandler(void)
//{
//    /* enter interrupt */
//    
//    
//    if(LL_DMA_IsActiveFlag_TC1(DMA1) != RESET){
//        serial_isr(stm32_serial[6],SERIAL_INT_DMARXDONE);
//        LL_DMA_ClearFlag_TC1(DMA1);
//    }
//    
//    if(LL_DMA_IsActiveFlag_HT1(DMA1) != RESET){
//        LL_DMA_ClearFlag_HT1(DMA1);
//    }
//    
//    if(LL_DMA_IsActiveFlag_TE1(DMA1) != RESET){
//        LL_DMA_ClearFlag_TE1(DMA1);
//    }
//    
//    if(LL_DMA_IsActiveFlag_DME1(DMA1) != RESET){
//        LL_DMA_ClearFlag_DME1(DMA1);
//    }
//    /* exit interrupt */
//    
//}

//void DMA1_Stream3_IRQHandler(void)
//{
//    /* enter interrupt */
//    
//    
//    if(LL_DMA_IsActiveFlag_TC3(DMA1) != RESET){
//        serial_isr(stm32_serial[6],SERIAL_INT_DMARXDONE);
//        LL_DMA_ClearFlag_TC3(DMA1);
//    }
//    
//    if(LL_DMA_IsActiveFlag_HT3(DMA1) != RESET){
//        LL_DMA_ClearFlag_HT3(DMA1);
//    }
//    
//    if(LL_DMA_IsActiveFlag_TE3(DMA1) != RESET){
//        LL_DMA_ClearFlag_TE3(DMA1);
//    }
//    
//    if(LL_DMA_IsActiveFlag_DME3(DMA1) != RESET){
//        LL_DMA_ClearFlag_DME3(DMA1);
//    }
//    /* exit interrupt */
//    
//}



void DMA1_Stream1_IRQHandler(void)
{
    /* enter interrupt */
    
    
    if(LL_DMA_IsActiveFlag_TC1(DMA1) != RESET){
        LL_DMA_DisableStream(DMA1, LL_DMA_STREAM_1);
        serial_isr(stm32_serial[2],SERIAL_INT_DMARXDONE);
        LL_DMA_SetDataLength(DMA1, LL_DMA_STREAM_1, SERIAL_DMA_RX_BUFFER_LENGTH);
        LL_DMA_EnableStream(DMA1, LL_DMA_STREAM_1);
        LL_DMA_ClearFlag_TC1(DMA1);
    }
    
    if(LL_DMA_IsActiveFlag_HT1(DMA1) != RESET){
        LL_DMA_ClearFlag_HT1(DMA1);
    }
    
    if(LL_DMA_IsActiveFlag_TE1(DMA1) != RESET){
        LL_DMA_ClearFlag_TE1(DMA1);
    }
    
    if(LL_DMA_IsActiveFlag_DME1(DMA1) != RESET){
        LL_DMA_ClearFlag_DME1(DMA1);
    }
    /* exit interrupt */
    
}


/*  for uart3 tx */
void DMA1_Stream3_IRQHandler(void)
{
    /* enter interrupt */
    
    
    if(LL_DMA_IsActiveFlag_TC3(DMA1) != RESET){
        serial_isr(stm32_serial[2],SERIAL_INT_DMATXDONE);
        LL_DMA_ClearFlag_TC3(DMA1);
    }
    
    if(LL_DMA_IsActiveFlag_HT3(DMA1) != RESET){
        LL_DMA_ClearFlag_HT3(DMA1);
    }
    
    if(LL_DMA_IsActiveFlag_TE3(DMA1) != RESET){
        LL_DMA_ClearFlag_TE3(DMA1);
    }
    
    if(LL_DMA_IsActiveFlag_DME3(DMA1) != RESET){
        LL_DMA_ClearFlag_DME3(DMA1);
    }
    /* exit interrupt */
    
}



// DMA handler for uart8 tx
//void DMA1_Stream0_IRQHandler(void)
//{
//    /* enter interrupt */
//    
//    
//    if(LL_DMA_IsActiveFlag_TC0(DMA1) != RESET){
//        serial_isr(stm32_serial[7],SERIAL_INT_DMATXDONE);
//        LL_DMA_ClearFlag_TC0(DMA1);
//    }
//    
//    if(LL_DMA_IsActiveFlag_HT0(DMA1) != RESET){
//        LL_DMA_ClearFlag_HT0(DMA1);
//    }
//    
//    if(LL_DMA_IsActiveFlag_TE0(DMA1) != RESET){
//        LL_DMA_ClearFlag_TE0(DMA1);
//    }
//    
//    if(LL_DMA_IsActiveFlag_DME0(DMA1) != RESET){
//        LL_DMA_ClearFlag_DME0(DMA1);
//    }
//    /* exit interrupt */
//    
//}



void DMA1_Stream6_IRQHandler(void)
{
    /* enter interrupt */
    
    
    if(LL_DMA_IsActiveFlag_TC6(DMA1) != RESET){
        LL_DMA_DisableStream(DMA1, LL_DMA_STREAM_6);
        serial_isr(stm32_serial[7],SERIAL_INT_DMARXDONE);
        LL_DMA_SetDataLength(DMA1, LL_DMA_STREAM_6, SERIAL_DMA_RX_BUFFER_LENGTH);
        LL_DMA_EnableStream(DMA1, LL_DMA_STREAM_6);
        LL_DMA_ClearFlag_TC6(DMA1);
    }
    
    if(LL_DMA_IsActiveFlag_HT6(DMA1) != RESET){
        LL_DMA_ClearFlag_HT6(DMA1);
    }
    
    if(LL_DMA_IsActiveFlag_TE6(DMA1) != RESET){
        LL_DMA_ClearFlag_TE6(DMA1);
    }
    
    if(LL_DMA_IsActiveFlag_DME6(DMA1) != RESET){
        LL_DMA_ClearFlag_DME6(DMA1);
    }
    /* exit interrupt */
    
}

/* dma rx handler for uart1 */
void DMA2_Stream1_IRQHandler(void)
{
    /* enter interrupt */
    
    
    if(LL_DMA_IsActiveFlag_TC1(DMA2) != RESET){
        LL_DMA_DisableStream(DMA2, LL_DMA_STREAM_1);
        serial_isr(stm32_serial[5],SERIAL_INT_DMARXDONE);
        LL_DMA_SetDataLength(DMA2, LL_DMA_STREAM_1, SERIAL_DMA_RX_BUFFER_LENGTH);
        LL_DMA_EnableStream(DMA2, LL_DMA_STREAM_1);
        LL_DMA_ClearFlag_TC1(DMA2);
    }
    
    if(LL_DMA_IsActiveFlag_HT1(DMA2) != RESET){
        LL_DMA_ClearFlag_HT1(DMA2);
    }
    
    if(LL_DMA_IsActiveFlag_TE1(DMA2) != RESET){
        LL_DMA_ClearFlag_TE1(DMA2);
    }
    
    if(LL_DMA_IsActiveFlag_DME1(DMA2) != RESET){
        LL_DMA_ClearFlag_DME1(DMA2);
    }
    /* exit interrupt */
    
}


void DMA1_Stream7_IRQHandler(void)
{
    /* enter interrupt */
    
    
    if(LL_DMA_IsActiveFlag_TC7(DMA1) != RESET){
        serial_isr(stm32_serial[4],SERIAL_INT_DMATXDONE);
        LL_DMA_ClearFlag_TC7(DMA1);
    }
    
    if(LL_DMA_IsActiveFlag_HT7(DMA1) != RESET){
        LL_DMA_ClearFlag_HT7(DMA1);
    }
    
    if(LL_DMA_IsActiveFlag_TE7(DMA1) != RESET){
        LL_DMA_ClearFlag_TE7(DMA1);
    }
    
    if(LL_DMA_IsActiveFlag_DME7(DMA1) != RESET){
        LL_DMA_ClearFlag_DME7(DMA1);
    }
    /* exit interrupt */
    
}

/* dma rx handler for uart1 */
void DMA2_Stream2_IRQHandler(void)
{
    /* enter interrupt */
    
    
    if(LL_DMA_IsActiveFlag_TC2(DMA2) != RESET){
        LL_DMA_DisableStream(DMA2, LL_DMA_STREAM_2);
        serial_isr(stm32_serial[0],SERIAL_INT_DMARXDONE);
        LL_DMA_SetDataLength(DMA2, LL_DMA_STREAM_2, SERIAL_DMA_RX_BUFFER_LENGTH);
        LL_DMA_EnableStream(DMA2, LL_DMA_STREAM_2);
        LL_DMA_ClearFlag_TC2(DMA2);
    }
    
    if(LL_DMA_IsActiveFlag_HT2(DMA2) != RESET){
        LL_DMA_ClearFlag_HT2(DMA2);
    }
    
    if(LL_DMA_IsActiveFlag_TE2(DMA2) != RESET){
        LL_DMA_ClearFlag_TE2(DMA2);
    }
    
    if(LL_DMA_IsActiveFlag_DME2(DMA2) != RESET){
        LL_DMA_ClearFlag_DME2(DMA2);
    }
    /* exit interrupt */
    
}


void DMA2_Stream6_IRQHandler(void)
{
    /* enter interrupt */
    
    
    if(LL_DMA_IsActiveFlag_TC6(DMA2) != RESET){
        serial_isr(stm32_serial[5],SERIAL_INT_DMATXDONE);
        LL_DMA_ClearFlag_TC6(DMA2);
    }
    
    if(LL_DMA_IsActiveFlag_HT6(DMA2) != RESET){
        LL_DMA_ClearFlag_HT6(DMA2);
    }
    
    if(LL_DMA_IsActiveFlag_TE6(DMA2) != RESET){
        LL_DMA_ClearFlag_TE6(DMA2);
    }
    
    if(LL_DMA_IsActiveFlag_DME6(DMA2) != RESET){
        LL_DMA_ClearFlag_DME6(DMA2);
    }
    /* exit interrupt */
    
}


 

void DMA2_Stream7_IRQHandler(void)
{
    /* enter interrupt */
    
    
    if(LL_DMA_IsActiveFlag_TC7(DMA2) != RESET){
        serial_isr(stm32_serial[0],SERIAL_INT_DMATXDONE);
        LL_DMA_ClearFlag_TC7(DMA2);
    }
    
    if(LL_DMA_IsActiveFlag_HT7(DMA2) != RESET){
        LL_DMA_ClearFlag_HT7(DMA2);
    }
    
    if(LL_DMA_IsActiveFlag_TE7(DMA2) != RESET){
        LL_DMA_ClearFlag_TE7(DMA2);
    }
    
    if(LL_DMA_IsActiveFlag_DME7(DMA2) != RESET){
        LL_DMA_ClearFlag_DME7(DMA2);
    }
    /* exit interrupt */
    
}




